package com.guos.script.groovy;

import javax.script.Bindings;
import javax.script.Compilable;
import javax.script.CompiledScript;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.SimpleBindings;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class GroovyScriptExecutor {

    private final Map<String, CompiledScript> scriptCacheMap = new ConcurrentHashMap<>();

    private ScriptEngine scriptEngine;

    public void init() {
        ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
        scriptEngine = scriptEngineManager.getEngineByName("groovy");
    }

    void load(String name, String script) {
        try {
            CompiledScript compiledScript = ((Compilable) scriptEngine).compile(script);
            scriptCacheMap.put(name, compiledScript);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    public Object execute(String name, Map<String, Object> paramsMap) throws Exception {
        try {
            CompiledScript compiledScript = scriptCacheMap.get(name);
            if (compiledScript == null) {
                throw new RuntimeException("");
            }
            Bindings bindings = new SimpleBindings();
            // 置入参数
            paramsMap.forEach(bindings::putIfAbsent);
            return compiledScript.eval(bindings);
        } catch (Exception e) {
            throw e;
        }
    }

    public static void main(String[] args) throws Exception {
        GroovyScriptExecutor groovyScriptExecutor = new GroovyScriptExecutor();
        groovyScriptExecutor.init();
        People people = new People();
        people.setName("guos");
        people.setAge(123);
        Map<String, Object> map = new HashMap<>();
        map.put("people", people);

        groovyScriptExecutor.load("xxx", "println(people.getAge());import com.guos.script.groovy.Student;Student student = new Student();return false;");
        Object xxx = groovyScriptExecutor.execute("xxx", map);
        Object xxx1 = groovyScriptExecutor.execute("xxx", Collections.emptyMap());
    }

}